package com.airticketbooking.common.utils;

import cn.hutool.core.util.StrUtil;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

@Slf4j
@Data
@Accessors(chain = true, fluent = true)
public class CookieBuilder {
    private Charset charset = StandardCharsets.UTF_8; // 设置字符集
    private int maxAge = -1; // 默认的过期时间
    private String path = "/"; // Cookie的路径
    private boolean httpOnly; // 是否HttpOnly
    private String name; // Cookie名称
    private String value; // Cookie值
    private String domain; // Cookie的域
    private final HttpServletRequest request; // HttpServletRequest
    private final HttpServletResponse response; // HttpServletResponse

    public CookieBuilder(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
    }

    /**
     * 构建cookie，会对cookie值用UTF-8做URL编码，避免中文乱码
     */
    public void build() {
        if (response == null) {
            log.error("response为null，无法写入cookie");
            return;
        }
        // 对cookie的值进行URL编码
        Cookie cookie = new Cookie(name, encodeValue(value));

        // 设置域
        if (StrUtil.isNotBlank(domain)) {
            cookie.setDomain(domain);
        } else if (request != null) {
            String serverName = request.getServerName();
            serverName = StrUtil.subAfter(serverName, ".", false);
            cookie.setDomain("." + serverName);
        }
        // 设置其他属性
        cookie.setHttpOnly(httpOnly);
        cookie.setMaxAge(maxAge);
        cookie.setPath(path);

        log.debug("生成cookie，编码方式:{}，【{}={}，domain:{};maxAge={};path={};httpOnly={}】",
                charset.name(), name, value, domain, maxAge, path, httpOnly);

        response.addCookie(cookie); // 将cookie添加到响应中
    }

    /**
     * 对cookie值进行URL编码
     * @param value cookie值
     * @return 编码后的值
     */
    private String encodeValue(String value) {
        try {
            return URLEncoder.encode(value, charset.name());
        } catch (UnsupportedEncodingException e) {
            log.error("Cookie值编码失败", e);
            return value; // 如果编码失败，返回原始值
        }
    }

    /**
     * 利用UTF-8对cookie值解码，避免中文乱码问题
     * @param cookieValue cookie原始值
     * @return 解码后的值
     */
    public static String decode(String cookieValue) throws UnsupportedEncodingException {
        return URLDecoder.decode(cookieValue, StandardCharsets.UTF_8.name());
    }
}
